package com.colabo.j2ee.web.core.log;

import java.io.IOException;
import java.security.Principal;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.log4j.NDC;

import com.colabo.j2ee.web.core.common.SessionConstants;

/**
 * 通过filter，把登录用户名作为当前log4j的标志保存在NDC（nested diagnostic context）环境中，以用于PERREQUEST的记录,适应多线程多客户端的记录应用，而NDC的标志将在request执行完后删除 ：<br>
 * logback中也有类似的功能，称为MDC(Mapped Diagnostic Contexts)，用法类似
 * web.xml中的配置如下:<br>
 * &lt;filter&gt; <br>
 * 		&lt;filter-name&gt;Logger Filter&lt;/filter-name&gt; <br>
 * 		&lt;filter-class&gt;com.cib.cap.base.common.log.LoggerFilter &lt;/filter-class&gt;<br>
 * &lt;/filter&gt; <br>
 * &lt;filter-mapping&gt;<br>
 *  	&lt;filter-name&gt;Logger Filter&lt;/filter-name&gt;<br>
 * 		&lt;url-pattern&gt;/*&lt;/url-pattern&gt;<br>
 * &lt;/filter-mapping&gt;<br>
 * 
 * 还需要在配置文件中的布局格式中一定要加上%x,如下<br>
 * &lt;param name="ConversionPattern" value="%d{dd/MM/yy HH:mm:ss.SSS};%p;%x %m%n"/&gt;<br>
 */
public class LoggerFilter implements Filter {
	boolean	userRegistered	= false;

	public void destroy() {
	}

	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
			ServletException {
		HttpServletRequest req = (HttpServletRequest) request;
		Principal principal = req.getUserPrincipal();
		String loginName;
		if (principal != null) {
			loginName = principal.getName();
			registerUsername(loginName);
		} else {
			HttpSession session = req.getSession();
			loginName = (String) session.getAttribute(SessionConstants.MDCKEY);
			registerUsername(loginName);
		}

		try {
			chain.doFilter(request, response);			
		} finally {
			if (userRegistered) { 
				NDC.pop();
				NDC.remove();
			}
		}
	}

	public void init(FilterConfig arg0) throws ServletException {
	}

	private void registerUsername(String username) {
		if (username != null && username.trim().length() > 0) {
			NDC.push(username); 
		} else {
			NDC.push("UnAuthenticated");  
		}
		userRegistered = true;
	}
}
